home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / progutil / stdwin.zoo / textedit / editwin.c next >
C/C++ Source or Header  |  1990-03-30  |  8KB  |  464 lines

  1. /* Edit Windows */
  2. /* $Header: editwin.c,v 1.1 88/05/20 16:30:28 guido Locked $ */
  3.  
  4. /* The data structure exported by this module is intended to
  5.    be accessible to the caller;
  6.    the routines provided here don't duplicate operations that
  7.    can be done by calling text-edit or window routines directly.
  8.    Exception: ewreplace is like tereplace, but also clears
  9.    the 'saved' flag and sets the document size */
  10.  
  11. #include "stdwin.h"
  12. #include "tools.h"
  13. #include "editwin.h"
  14.  
  15. #define MAXFN 256 /* File name length */
  16.  
  17. #ifdef __STDC__
  18. static void ewdrawproc (WINDOW *win , int left , int top , int right , int
  19.               bottom );
  20. #else
  21. static void ewdrawproc();
  22. #endif
  23.  
  24. static int ewnum;
  25. static EDITWIN **ewlist;
  26.  
  27. EDITWIN *
  28. ewfind(win)
  29.     WINDOW *win;
  30. {
  31.     int i;
  32.  
  33.     if (win == NULL)
  34.         return NULL;
  35.  
  36.     i= wgettag(win);
  37.     
  38.     if (i >= 0 && i < ewnum &&
  39.             ewlist[i] != NULL && ewlist[i]->win == win)
  40.         return ewlist[i];
  41.     else
  42.         return NULL;
  43. }
  44.  
  45. int
  46. ewcount()
  47. {
  48.     int count= 0;
  49.     int i;
  50.     for (i= 0; i < ewnum; ++i) {
  51.         if (ewlist[i] != NULL)
  52.             ++count;
  53.     }
  54.     return count;
  55. }
  56.  
  57. static void
  58. ewdrawproc(win, left, top, right, bottom)
  59.     WINDOW *win;
  60.      int left, top, right, bottom;
  61. {
  62.     EDITWIN *ew= ewfind(win);
  63.     if (ew != NULL)
  64.         tedrawnew(ew->tp, left, top, right, bottom);
  65. }
  66.  
  67. EDITWIN *
  68. ewcreate(filename)
  69.     char *filename;
  70. {
  71.     EDITWIN *ew= ALLOC(EDITWIN);
  72.     int width, height;
  73.     int i;
  74.     
  75.     if (ew == NULL)
  76.         return NULL;
  77.     ew->win= wopen(filename==NULL ? "Untitled" : filename, ewdrawproc);
  78.     if (ew->win == NULL) {
  79.         FREE(ew);
  80.         return NULL;
  81.     }
  82.     wgetwinsize(ew->win, &width, &height);
  83.     ew->tp= tecreate(ew->win, 0, 0, width, height);
  84.     if (ew->tp == NULL) {
  85.         wclose(ew->win);
  86.         FREE(ew);
  87.         return NULL;
  88.     }
  89.     if (filename != NULL) {
  90.         if (!ewreadfile(ew, filename)) {
  91.             tefree(ew->tp);
  92.             wclose(ew->win);
  93.             FREE(ew);
  94.             return NULL;
  95.         }
  96.     }
  97.     ew->filename= strdup(filename);
  98.     ew->saved= TRUE;
  99.     for (i= 0; i < ewnum; ++i) {
  100.         if (ewlist[i] == NULL)
  101.             break;
  102.     }
  103.     wsettag(ew->win, i);
  104.     if (i >= ewnum) {
  105.         L_APPEND(ewnum, ewlist, EDITWIN*, NULL);
  106.     }
  107.     ewlist[i]= ew;
  108.     return ew;
  109. }
  110.  
  111. EDITWIN *
  112. ewnew()
  113. {
  114.     return ewcreate((char*)NULL);
  115. }
  116.  
  117. EDITWIN *
  118. ewopen()
  119. {
  120.     char filename[MAXFN];
  121.     
  122.     filename[0]= EOS;
  123.     if (waskfile("Open file:", filename, (int)(sizeof filename), FALSE))
  124.         return ewcreate(filename);
  125.     else
  126.         return NULL;
  127. }
  128.  
  129. bool
  130. ewclose(ew)
  131.     EDITWIN *ew;
  132. {
  133.     int i;
  134.     
  135.     if (!ew->saved) {
  136.         char buf[MAXFN+25];
  137.         sprintf(buf, "Save changes to \"%s\" before closing?",
  138.             ew->filename==NULL ? "Untitled" : ew->filename);
  139.         switch (waskync(buf, 1)) {
  140.         case -1:
  141.             return FALSE;
  142.         case 0:
  143.             break;
  144.         case 1:
  145.             if (!ewsave(ew))
  146.                 return FALSE;
  147.             break;
  148.         }
  149.     }
  150.     i= wgettag(ew->win);
  151.     if (i >= 0 && i < ewnum && ewlist[i] == ew)
  152.         ewlist[i]= NULL;
  153.     tefree(ew->tp);
  154.     wclose(ew->win);
  155.     FREE(ew->filename);
  156.     FREE(ew);
  157.     return TRUE;
  158. }
  159.  
  160. bool
  161. ewsave(ew)
  162.     EDITWIN *ew;
  163. {
  164.     if (ew->saved)
  165.         return TRUE;
  166.     if (!ew->filename)
  167.         return ewsaveas(ew);
  168.     return ew->saved= ewwritefile(ew, ew->filename);
  169. }
  170.  
  171. bool
  172. ewsaveas(ew)
  173.     EDITWIN *ew;
  174. {
  175.     return ewsaveprompt(ew, "Save as:", TRUE);
  176. }
  177.  
  178. bool
  179. ewsavecopy(ew)
  180.     EDITWIN *ew;
  181. {
  182.     return ewsaveprompt(ew, "Save a copy as:", FALSE);
  183. }
  184.  
  185. bool
  186. ewsaveprompt(ew, prompt, changefile)
  187.     EDITWIN *ew;
  188.     char *prompt;
  189.     bool changefile;
  190. {
  191.     char filename[MAXFN];
  192.     
  193.     filename[0]= EOS;
  194.     if (ew->filename != NULL) {
  195.         strncpy(filename, ew->filename, (size_t)MAXFN);
  196.         filename[MAXFN-1]= EOS;
  197.     }
  198.     if (!waskfile(prompt, filename, (int)(sizeof filename), TRUE))
  199.         return FALSE;
  200.     if (!ewwritefile(ew, filename))
  201.         return FALSE;
  202.     if (changefile) {
  203.         FREE(ew->filename);
  204.         ew->filename= strdup(filename);
  205.         wsettitle(ew->win, filename);
  206.         ew->saved= TRUE;
  207.     }
  208.     return TRUE;
  209. }
  210.  
  211. bool
  212. ewrevert(ew)
  213.     EDITWIN *ew;
  214. {
  215.     char buf[MAXFN+50];
  216.     
  217.     if (ew->saved)
  218.         return TRUE;
  219.     if (ew->filename == NULL) {
  220.         wmessage("Not saved yet");
  221.         return FALSE;
  222.     }
  223.     sprintf(buf, "Discard changes since last save to \"%s\" ?",
  224.         ew->filename);
  225.     if (waskync(buf, 1) < 1)
  226.         return FALSE;
  227.     return ewreadfile(ew, ew->filename);
  228. }
  229.  
  230. bool
  231. ewreadfile(ew, filename)
  232.     EDITWIN *ew;
  233.     char *filename;
  234. {
  235.     FILE *fp= fopen(filename, "r");
  236.     long size, ftell();
  237.     char *buf;
  238.     
  239.     if (fp == NULL) {
  240.         wperror(filename);
  241.         return FALSE;
  242.     }
  243.     if (fseek(fp, 0L, 2) == -1) {
  244.         wperror (filename);
  245.         fclose (fp);
  246.         return FALSE;
  247.     }
  248.     size= ftell(fp);
  249.     if (size >= 1L<<15) {
  250.         char buf[MAXFN + 50];
  251.         sprintf(buf, "File \"%s\" is big (%d K).  Still edit?",
  252.             filename, (int) ((size+1023)/1024));
  253.         if (waskync(buf, 1) < 1) {
  254.             fclose(fp);
  255.             return FALSE;
  256.         }
  257.     }
  258.     buf= malloc((size_t)size);
  259.     if (buf == NULL) {
  260.         wmessage("Can't get memory for buffer");
  261.         fclose(fp);
  262.         return FALSE;
  263.     }
  264.     if (fseek(fp, 0L, 0) == -1) {
  265.         wperror (filename);
  266.         fclose (fp);
  267.         return FALSE;
  268.     }
  269.     if ((size = fread(buf, 1, (int) size, fp)) == -1) {
  270.         wmessage("Read error");
  271.         fclose(fp);
  272.         return FALSE;
  273.     }
  274.     fclose(fp);
  275.     tesetbuf(ew->tp, buf, (int) size); /* Gives the buffer away! */
  276.     ew->saved= TRUE;
  277.     ewsetdimensions(ew);
  278.     return TRUE;
  279. }
  280.  
  281. void 
  282. ewsetdimensions(ew)
  283.     EDITWIN *ew;
  284. {
  285.     int width, height;
  286.     
  287.     wgetwinsize(ew->win, &width, &height);
  288.     wsetdocsize(ew->win, width, wlineheight() * tegetnlines(ew->tp));
  289. }
  290.  
  291. bool
  292. ewwritefile(ew, filename)
  293.     EDITWIN *ew;
  294.     char *filename;
  295. {
  296.     FILE *fp= fopen(filename, "w");
  297.     char *buf;
  298.     int len, nwritten;
  299.     
  300.     if (fp == NULL) {
  301.         wperror(filename);
  302.         return FALSE;
  303.     }
  304.     buf= tegettext(ew->tp);
  305.     len= (int)strlen(buf);
  306.     nwritten= fwrite(buf, 1, len, fp);
  307.     fclose(fp);
  308.     if (nwritten != len) {
  309.         wmessage("Write error");
  310.         return FALSE;
  311.     }
  312.     /* Can't set saved to TRUE, because of 'save a copy' */
  313.     return TRUE;
  314. }
  315.  
  316. bool
  317. ewevent(ew, e, closed_return)
  318.     EDITWIN *ew;
  319.     EVENT *e;
  320.     bool *closed_return;
  321. {
  322.     bool closed= FALSE;
  323.     bool change= FALSE;
  324.     
  325.     if (ew == NULL) {
  326.         ew= ewfind(e->window);
  327.         if (ew == NULL)
  328.             return FALSE;
  329.     }
  330.     else if (e->window != ew->win)
  331.         return FALSE;
  332.     
  333.     switch (e->type) {
  334.     
  335.     case WE_ACTIVATE:
  336.         break;
  337.         
  338.     case WE_SIZE:
  339.         {
  340.             int width, height;
  341.             wgetwinsize(ew->win, &width, &height);
  342.             temovenew(ew->tp, 0, 0, width, height);
  343.             ewsetdimensions(ew);
  344.         }
  345.         break;
  346.         
  347.     case WE_COMMAND:
  348.         if (e->u.command == WC_CLOSE) {
  349.             closed= ewclose(ew);
  350.             break;
  351.         }
  352.         /* Else, fall through */
  353.         if (e->u.command == WC_RETURN ||
  354.             e->u.command == WC_TAB ||
  355.             e->u.command == WC_BACKSPACE)
  356.             change= TRUE;
  357.             goto def;
  358.     
  359.     case WE_MOUSE_DOWN:
  360.         /* Edit the coordinates slightly so teevent always
  361.            believes it is in the rect */
  362.         {
  363.             int left= tegetleft(ew->tp);
  364.             int right= tegetright(ew->tp);
  365.             int top= tegettop(ew->tp);
  366.             int bottom= tegetbottom(ew->tp);
  367.             CLIPMIN(e->u.where.h, left);
  368.             CLIPMAX(e->u.where.h, right);
  369.             CLIPMIN(e->u.where.v, top);
  370.             if (e->u.where.v >= bottom) {
  371.                 e->u.where.v= bottom;
  372.                 e->u.where.h= right;
  373.             }
  374.         }
  375.         /* Fall through */
  376.     default:
  377.     def:
  378.         if (!teevent(ew->tp, e))
  379.             return FALSE;
  380.         if (e->type == WE_CHAR)
  381.             change= TRUE;
  382.         if (change) {
  383.             ew->saved= FALSE;
  384.             ewsetdimensions(ew);
  385.         }
  386.         break;
  387.         
  388.     }
  389.     
  390.     if (closed_return != NULL)
  391.         *closed_return= closed;
  392.     return TRUE;
  393. }
  394.  
  395. bool
  396. ewsaveall()
  397. {
  398.     int i;
  399.     
  400.     for (i= 0; i < ewnum; ++i) {
  401.         if (ewlist[i] != NULL && !ewsave(ewlist[i]))
  402.             return FALSE;
  403.     }
  404.     return TRUE;
  405. }
  406.  
  407. bool
  408. ewcloseall()
  409. {
  410.     int i;
  411.     
  412.     for (i= 0; i < ewnum; ++i) {
  413.         if (ewlist[i] != NULL && !ewclose(ewlist[i]))
  414.             return FALSE;
  415.     }
  416.     return TRUE;
  417. }
  418.  
  419. void
  420. ewreplace(ew, str)
  421.     EDITWIN *ew;
  422.     char *str;
  423. {
  424.     if (*str == EOS && tegetfoc1(ew->tp) == tegetfoc2(ew->tp))
  425.         return;
  426.     tereplace(ew->tp, str);
  427.     ew->saved= FALSE;
  428.     ewsetdimensions(ew);
  429. }
  430.  
  431. void
  432. ewundo(ew)
  433.     EDITWIN *ew;
  434. {
  435.     wfleep();
  436. }
  437.  
  438. void
  439. ewcopy(ew)
  440.     EDITWIN *ew;
  441. {
  442.     int f1= tegetfoc1(ew->tp);
  443.     int f2= tegetfoc2(ew->tp);
  444.     char *text;
  445.     if (f1 == f2)
  446.         wfleep();
  447.     else {
  448.         text= tegettext(ew->tp);
  449.         wsetclip(text+f1, f2-f1);
  450.     }
  451.         
  452. }
  453.  
  454. void
  455. ewpaste(ew)
  456.     EDITWIN *ew;
  457. {
  458.     char *text= wgetclip();
  459.     if (text == NULL)
  460.         wfleep();
  461.     else
  462.         ewreplace(ew, text);
  463. }
  464.